package br.unifor.ed.tads;

import br.unifor.ed.exceptions.InvalidPositionException;
import br.unifor.ed.exceptions.ListEmptyException;
import br.unifor.ed.exceptions.ListFullException;

public class ArrayBasedIntList implements IntList {
	private int[] data;
	private int last;

	public ArrayBasedIntList(int size) {
		super();
		data = new int[size];
		setLast(0);
	}

	public int getLast() {
		return last;
	}

	public void setLast(int last) {
		this.last = last;
	}

	public boolean isEmpty() {
		return (getLast() == 0);
	}

	public boolean isFull() {
		return (getLast() == data.length);
	}

	public void addFirst(int newData) throws ListFullException {
		if (isFull())
			throw new ListFullException(this.getClass().getName());

		// Deslocar dos elementos já existentes para adicionar novo no in�cio
		for (int i = getLast(); i > 0; i--)
			data[i] = data[i - 1];

		data[0] = newData;
		incrementLast();
	}

	private void incrementLast() {
		setLast(getLast() + 1);
	}

	public void print() throws ListEmptyException {
		if (isEmpty())
			throw new ListEmptyException(this.getClass().getName());

		System.out.println("Exibição dos elementos da lista...");
		for (int i = 0; i < getLast(); i++)
			System.out.printf("Posição(%d): %d.\n", i + 1, data[i]);

	}

	public void addLast(int newData) throws ListFullException {
		if (isFull())
			throw new ListFullException(this.getClass().getName());

		data[getLast()] = newData;
		incrementLast();

	}

	public int size() {
		return (getLast());
	}

	public void addAt(int position, int newData) throws ListFullException,
			InvalidPositionException {
		if (isFull())
			throw new ListFullException(this.getClass().getName());

		if ((position < 1) || (position > size() + 1))
			throw new InvalidPositionException(position);

		for (int i = size(); i >= position; i--)
			data[i] = data[i - 1];

		data[position - 1] = newData;
		incrementLast();
	}

	public int revomeFirst() throws ListEmptyException {
		if (isEmpty())
			throw new ListEmptyException(this.getClass().getName());

		int removedValue = data[0];
		for (int i = 1; i < size(); i++)
			data[i - 1] = data[i];
		decrementLast();

		return (removedValue);
	}

	private void decrementLast() {
		setLast(getLast() - 1);
	}

	public int removeLast() throws ListEmptyException {
		if (isEmpty())
			throw new ListEmptyException(this.getClass().getName());

		int removedValue = data[size() - 1];
		decrementLast();

		return (removedValue);
	}

	public int removeAt(int position) throws ListEmptyException,
			InvalidPositionException {

		if (isEmpty())
			throw new ListEmptyException(this.getClass().getName());
		if ((position < 1) || (position > size()))
			throw new InvalidPositionException(position);

		int removedValue = data[position - 1];
		for (int i = position; i < size(); i++)
			data[i - 1] = data[i];
		decrementLast();

		return (removedValue);
	}

}
